package character;

import character.action.BuildAction;
import character.action.CharacterAction;
import character.action.MoveAction;
import character.action.HarvestAction;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import character.ai.AbstractAIControl;
import com.jme3.export.JmeImporter;
import java.io.IOException;
import mygame.MyCharacterControl;

public class CharacterAIControl extends AbstractAIControl {
    protected AbstractCharacter thisCharacter;
    private float tpf;

    public CharacterAIControl() {}

    @Override
    protected void controlUpdate(float tpf) {
        this.tpf = tpf;
	handleCurrentAction();
	super.controlUpdate(tpf);
    }

    protected void handleCurrentAction() {
	if(thisCharacter.hasAction()) {
	    CharacterAction action = thisCharacter.getCurrentAction();
	    if(action instanceof MoveAction)
		handleMoveAction((MoveAction)action);
	    else if(action instanceof HarvestAction)
		handleDigAction((HarvestAction)action);
	    else if(action instanceof BuildAction)
		handleBuildAction((BuildAction)action);
	}
    }

    /** This is where pathfinding takes place. It should set the current move direction this tick on the character status object. */
    public void handleMoveAction(MoveAction moveAction) {
	Vector3f newDir = moveAction.getTargetLocation().clone();
	//compare current location to target at foot-level of the char
	newDir.subtractLocal(spatial.getControl(MyCharacterControl.class).getFeetWorldTranslation());
	newDir.setY(0f); //set y to 0 before we save the new direction, because the character control won't do it
	if(newDir.length() < moveAction.getStopDistanceThreshold()) {
	    System.out.println("clearing move target");
	    thisCharacter.completeCurrentAction();
	    newDir = Vector3f.ZERO;
	}
	thisCharacter.getStatus().setMoveDir(newDir);
    }

    public void handleDigAction(HarvestAction digAction) {
	boolean completed = digAction.tick(tpf, thisCharacter);
	if(completed)
	    thisCharacter.completeCurrentAction();
    }

    public void handleBuildAction(BuildAction buildAction) {
	boolean completed = buildAction.tick(tpf, thisCharacter);
	if(completed)
	    thisCharacter.completeCurrentAction();
    }

    @Override
    public void collideWith(Spatial collidingSpatial) {
        
    }
    
    public void setRandomWalkDirection() {
	Vector3f newDir = new Vector3f(FastMath.rand.nextFloat(), 0f, FastMath.rand.nextFloat());
	if(FastMath.rand.nextInt(2) == 1)
	    newDir.setX(newDir.getX()*-1);
	if(FastMath.rand.nextInt(2) == 1)
	    newDir.setZ(newDir.getZ()*-1);
	thisCharacter.getStatus().setMoveDir(newDir);
    }

    @Override
    public void setSpatial(Spatial spatial) {
	super.setSpatial(spatial);
	thisCharacter = (AbstractCharacter)spatial;
    }

    @Override
    public Control cloneForSpatial(Spatial spatial) {
	CharacterAIControl control = new CharacterAIControl();
        // copy custom properties here?
        spatial.addControl(control);
        return control;
    }

    @Override
    public void read(JmeImporter im) throws IOException {
	super.read(im);
	thisCharacter = (AbstractCharacter)spatial;
    }
}
